package com.example.movie.data.cinema.model

import android.util.Log
import com.example.movie.common.dao.SimpleMovieData
import com.example.movie.common.entity.Agent
import com.example.movie.common.entity.Plan
import com.example.movie.common.exception.RemoteServerException
import com.example.movie.common.model.Result
import com.example.movie.common.model.ResultCode
import com.example.movie.common.request.CinemaService
import com.example.movie.data.cinema.model.vo.CinemaDetailVo
import com.example.movie.data.cinema.model.vo.CinemaVo
import com.example.movie.data.cinema.model.vo.SeatVo
import com.example.movie.utils.DbUtil
import com.example.movie.utils.RequestUtil
import java.io.IOException
import java.net.UnknownServiceException

class CinemaDataSource {

    private val cinemaService: CinemaService = RequestUtil.getService(CinemaService::class.java)

    fun getCinemaData(cityId: String, hallTypeId: Int, price: Int, star: Int): Result<CinemaVo>? {
        return try {
            val res = cinemaService.agent(cityId, hallTypeId).execute().body()!!
            if (res.success) {
                val cinemaDao = DbUtil.getInstance().cinemaDao()
                cinemaDao.deleteAllAgents()
                cinemaDao.insertAllAgents(res.data?.agentList)
                res.data?.agentList = cinemaDao.getAgentCondition(price, star)
                Result.Success(res.data)
            } else {
                when (res.code) {
                    ResultCode.REMOTE_SERVER_ERROR.value -> throw RemoteServerException(res.message)
                    else -> throw UnknownServiceException("未知异常!")
                }
            }
        } catch (e: Throwable) {
            Log.e("request error", e.toString())
            Result.Error(IOException("Error request", e))
        }
    }

    fun getCineMoviePlanData(agentId: Int): Result<CinemaDetailVo>? {
        return try {
            val res = cinemaService.agentDetail(agentId).execute().body()!!
            if (res.success) {
                //保存数据到数据库中
                val db = DbUtil.getInstance()
                var highScoreMoviePlan: List<Plan>? = null
                var planMovies: List<SimpleMovieData>? = null
                with(db.cinemaDao()) {
                    res.data?.let {
                        this.deleteAllPlanData()
                        this.insertAll(it.planVos)
                        highScoreMoviePlan = this.highScoreMoviePlan()
                        planMovies = this.planMovieImages()
                    }
                }
                //默认显示评分最高的电影
                res.data?.planVos = highScoreMoviePlan
                res.data?.planMovies = planMovies
                Result.Success(res.data)
            } else {
                when (res.code) {
                    ResultCode.REMOTE_SERVER_ERROR.value -> throw RemoteServerException(res.message)
                    else -> throw UnknownServiceException("未知异常!")
                }
            }
        } catch (e: Throwable) {
            Log.e("request error", e.toString())
            Result.Error(IOException("Error request", e))
        }

    }

    fun getMoviePlan(movieId: Int, playDay: String): List<Plan>? {
        val db = DbUtil.getInstance()
        with(db.cinemaDao()) {
            Log.e("debug", "getMoviePlan: movieId=$movieId playDay=$playDay")
            return loadByMovieIdAndPlayDay(movieId, playDay)
        }
    }

    fun getMoviePlanDateById(movieId: Int): List<String>? {
        val db = DbUtil.getInstance()
        with(db.cinemaDao()) {
            return this.planDates(movieId)
        }
    }

    fun loadSeatData(planId: Int): Result<SeatVo> {
        return try {
            val res = cinemaService.seat(planId).execute().body()!!
            if (res.success) {
                Result.Success(res.data)
            } else {
                when (res.code) {
                    ResultCode.REMOTE_SERVER_ERROR.value -> throw RemoteServerException(res.message)
                    else -> throw UnknownServiceException("未知异常!")
                }
            }
        } catch (e: Throwable) {
            Log.e("request error", e.toString())
            Result.Error(IOException("Error request", e))
        }
    }

    fun getCinemaByCondition(price: Int, star: Int): Result<List<Agent>> {
        val agents = DbUtil.getInstance().cinemaDao().getAgentCondition(star = star, price = price)
        return Result.Success(agents)
    }


}